#include "main.h"
#include "stm32f4xx_hal.h"
#include "stdio.h"
#include "gpio.h"
#include "usart.h"

#include "app.h"
#include "key.h"
#include "led.h"
#include "st7735.h"
#include "font.h"
#include "lvgl.h" 
#include "lv_port_disp_template.h" 

#include "FreeRTOS.h"
#include "task.h"


#define START_TASK_PRIO		1
#define LED_TASK_PRIO		5
#define USART_TASK_PRIO		5
#define KEY_TASK_PRIO		5
#define APP_TASK_PRIO		5
#define TEST_TASK_PRIO		5
#define DISPLAY_TASK_PRIO   5

#define START_STK_SIZE 		128 
#define LED_STK_SIZE 		128 
#define USART_STK_SIZE 		128 
#define KEY_STK_SIZE 		128 
#define APP_STK_SIZE 		(128)
#define TEST_TASK_SIZE      128
#define DISPLAY_TASK_SIZE   (128*4)


TaskHandle_t StartTask_Handler;
TaskHandle_t LedTask_Handler;
TaskHandle_t Usartask_Handler;
TaskHandle_t Keytask_Handler;
TaskHandle_t AppTask_Handler;
TaskHandle_t TestTask_Handler;
TaskHandle_t DisplayTask_Handler;

void start_task(void *pvParameters);

void SystemClock_Config(void);

void led_task(void *pvParameters);
void uart_task(void *pvParameters);
void test_task(void *pvParameters);


#ifdef __GUNC__
	
	#define	PUTCHAR_PROTOTYPE int __io_puchar(int ch) 

#else
	
	#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *fp)
	
#endif
    

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    
    MX_GPIO_Init();
    MX_USART1_UART_Init();
    MX_USART2_UART_Init();
    MX_SPI1_Init();

    
    xTaskCreate((TaskFunction_t )start_task,     
                (const char*    )"start_task",
                (uint16_t       )START_STK_SIZE,
                (void*          )NULL,                  
                (UBaseType_t    )START_TASK_PRIO,
                (TaskHandle_t*  )&StartTask_Handler);           
    vTaskStartScheduler();
    

}

void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();
 

//    xTaskCreate((TaskFunction_t )test_task,     	
//        (const char*    )"test_task",   	
//        (uint16_t       )TEST_TASK_SIZE, 
//        (void*          )NULL,				
//        (UBaseType_t    )TEST_TASK_PRIO,	
//        (TaskHandle_t*  )&TestTask_Handler); 
    
    xTaskCreate((TaskFunction_t )led_task,     	
                    (const char*    )"led0_task",   	
                    (uint16_t       )LED_STK_SIZE, 
                    (void*          )NULL,				
                    (UBaseType_t    )LED_TASK_PRIO,	
                    (TaskHandle_t*  )&LedTask_Handler);   
     
    
    xTaskCreate((TaskFunction_t )keyTask,     	
                (const char*    )"key_task",   	
                (uint16_t       )KEY_STK_SIZE, 
                (void*          )NULL,				
                (UBaseType_t    )KEY_TASK_PRIO,	
                (TaskHandle_t*  )&Keytask_Handler); 
                
    xTaskCreate((TaskFunction_t )app,     	
            (const char*    )"app_task",   	
            (uint16_t       )APP_STK_SIZE, 
            (void*          )NULL,				
            (UBaseType_t    )APP_TASK_PRIO,	
            (TaskHandle_t*  )&AppTask_Handler); 
            
   xTaskCreate((TaskFunction_t )display,     	
       (const char*    )"display_task",   	
       (uint16_t       )DISPLAY_TASK_SIZE, 
       (void*          )NULL,				
       (UBaseType_t    )DISPLAY_TASK_PRIO,	
       (TaskHandle_t*  )&DisplayTask_Handler); 



    vTaskDelete(StartTask_Handler); 
    taskEXIT_CRITICAL();           
}



void vApplicationTickHook()
{
	// 告诉lvgl已经过去了1毫秒
	lv_tick_inc(1);
}

void test_task(void *pvParameters)
{
   while(1)
   {
        vTaskDelay(pdMS_TO_TICKS(1000));
   }

}

void uart_task(void *pvParameters)
{
    
  while(1)
  {
    ;;
  }
}

void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}


void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 84;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}


